import { js_beautify } from "js-beautify";
import { convertWord } from "@/util/xc/utils";
import { btns, FUNC, operatorArr } from "./config";

/** 美化代码配置 */
const beautifyOptions = {
  preserve_newlines: false, // 保留空行
  // end_with_newline: true, // 在文件结尾保证有换行
  // "eol": ";",
  jslint_happy: true,
  autofocus: true
};
// 特殊公式
const StatisticalField = ["应发工资", "实发工资", "应税工资"];

/** 替换为可执行String */
export const getFormula = ({ str, checkingIn = [], payment = [] }, bol) => {
  console.groupCollapsed("开始替换字符串", str, operatorArr, JSON.parse(JSON.stringify(checkingIn)), JSON.parse(JSON.stringify(payment)), FUNC);
  const equation_name = str;
  // 特殊符号
  str = replaceSpecificSymbol(str);
  const salaryRule = filtrateLogic(str);
  // 按钮
  operatorArr.forEach(item => {
    if (item.isShift) str = replaceStr(str, item.label, item.actual);
  });
  // 美化代码
  str = codeBeautify(str, salaryRule);
  if (!bol) {
    checkingIn.forEach(item => {
      str = replaceStr(str, item.name, parseInt(Math.random() * 10), "#");
    });
    payment.forEach(item => {
      str = replaceStr(str, item.name, parseInt(Math.random() * 20) + 10, "#");
    });
    FUNC.forEach(item => {
      str = replaceStr(str, `${item.type}\\(`, `this.${item.type}(`);
    });
  } else {
    // #考勤字段#     |薪酬字段|    [统计字段]
    checkingIn.forEach(item => {
      str = replaceStr(str, item.name, `#${convertWord(item.name)}#`, "#");
    });
    payment.forEach(item => {
      const isStat = StatisticalField.find(n => item.name == n);
      const replaceName = isStat ? `[${convertWord(item.name)}]` : `|${convertWord(item.name)}|`;
      str = replaceStr(str, item.name, replaceName, "#");
    });
    // 固定替换 || &&
    str = replaceStr(str, "\\|\\|", "or");
    str = replaceStr(str, "&&", "and");
  }
  console.log(str);
  console.groupEnd();
  if (bol)
    return {
      equation: str,
      equation_name,
      salaryRule
    };
  return {
    str,
    salaryRule
  };
};

/** 特殊符号 */
const replaceSpecificSymbol = str => {
  console.groupCollapsed('筛选特殊字符', str);
  // 百分号
  str = replacePer(str);
  // 全角转半角
  str = CtoH(str);
  // str = str.replace(/[’|‘]/g, "'").replace(/[“|”]/g, "\"");
  // str = str.replace(/！/g, "!");
  // str = str.replace(/【/g, "[").replace(/】/g, "]").replace(/｛/g, "{").replace(/｝/g, "}");
  // str = str.replace(/，/g, ",").replace(/：/g, ":");
  // str = str.replace(/《/g, "<").replace(/》/g, ">");
  // str = str.replace(/。/g, ".").replace(/？/g, "?");
  // str = str.replace(/￥/g, "$");
  str = str.replace(/（/g, "(").replace(/）/g, ")");
  console.log(str);
  console.groupEnd();
  return str;
};

/** 替换百分比 */
const replacePer = str => {
  console.groupCollapsed("开始转换百分比", str);
  const per = new RegExp("[\\d|.]{0,}%", "g");
  const arr = str.matchAll(per);
  let o = arr.next();
  while (!o.done) {
    const n = o.value[0];
    str = str.replace(n, shiftPer(n));
    o = arr.next();
  }
  console.log(str);
  console.groupEnd();
  return str;
};


/** 全角转半角   */
const CtoH = (str) => {  
  var result = "";  
  for (var i = 0; i < str.length; i++) {  
    if (str.charCodeAt(i) == 12288) {  
      result += String.fromCharCode(str.charCodeAt(i) - 12256);  
      continue;  
    }  
    if (str.charCodeAt(i) > 65280 && str.charCodeAt(i) < 65375) {  
      result += String.fromCharCode(str.charCodeAt(i) - 65248);  
    }else{  
      result += String.fromCharCode(str.charCodeAt(i));  
    }  
  }  
  return result;  
}; 

/** 50% 转换 0.5 */
const shiftPer = s => Number(s.substr(0, s.length - 1)) / 100;

/** 美化代码 */
const codeBeautify = (str, salaryRule) => {
  console.log(str);
  const code = wipeBlank(js_beautify(str, beautifyOptions));
  if (salaryRule == 10) return codeStrict(code);
  else return code;
};

/** 去除空白 */
const wipeBlank = (str, sign = "#") => {
  const regExp = new RegExp(`${sign}.*?${sign}`, "g");
  const arr = str.matchAll(regExp);
  let o = arr.next();
  while (!o.done) {
    const n = o.value[0];
    const replaceValue = n.replace(/[\s]/g, "");
    // console.log(regExp, o, n, replaceValue);
    str = str.replace(n, replaceValue);
    o = arr.next();
  }
  console.log(str);
  return str;
};

/** 分号 */
const codeStrict = str => {
  const arr = str.split("\n");
  return arr
    .map(s => {
      if (![";", "{", "(", "["].includes(s[s.length - 1])) {
        return s + ";";
      }
      return s;
    })
    .join("\n");
};

/** 正则替换 */
const replaceStr = (str, name, replaceValue = parseInt(Math.random() * 10), sign = "") => {
  // console.group("正则替换", str, name, replaceValue);
  // (sign ? "\\" : "") +
  const regExp = new RegExp(sign + name + sign, "g");
  // console.log(regExp, replaceValue);
  // console.groupEnd();
  return str.replace(regExp, replaceValue + " ");
};

/** 正则筛选逻辑 */
const filtrateLogic = str => {
  const arr = btns
    .slice(0, 5)
    .flat(1)
    .join("")
    .split("");

  console.group("正则筛选逻辑", str, arr);
  // 消除函数
  FUNC.forEach(item => {
    const regExp = new RegExp("\\" + item.type + "\\(.*?\\)", "g");
    str = str.replace(regExp, "");
  });
  // 消除基础运算符
  arr.forEach(n => {
    const regExp = new RegExp("\\" + n, "g");
    str = str.replace(regExp, "");
  });
  // 消除##之间的内容
  str = str.replace(/#.*?#/g, "");
  // 消除空值
  str = str.replace(/\s*/g, "");
  // 消除数字和小数点
  str = str.replace(/[\d*]|[\\.]/g, "");
  console.log(str);
  console.groupEnd();
  return str ? 10 : 6;
};
